package algo3c3g3.view;

import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import algo3c3g3.controller.*;

/**
 * Esta clase gestiona todos los eventos de menu del programa.
 * Tambien provee la barra de menu armada.
 */
public class GameMenus
{
    private Controller controller;
    private JMenuBar menus = new JMenuBar();
    private JMenuItem menuItemPause;
    private JFileChooser fileChooser = new JFileChooser();
    private View window;
    
    
    // Estos metodos son llamados desde los listeners
    // de los eventos.
    
    private void pauseGame()
    {
        if(controller != null)
            controller.setPause(menuItemPause.isSelected());
    }
    
    private void exitGame()
    {
        finishGame();
        System.exit(0);
    }
    
    private void saveLevel()
    {
        if(controller == null)
        {
            window.showErrorMessage("No hay una partida activa para guardar.");
            return;
        }
        
        int res = fileChooser.showSaveDialog((JFrame)window);

        if(res == JFileChooser.APPROVE_OPTION)
        {
            File file = fileChooser.getSelectedFile();
            controller.saveLevel(file);
        }
    }
    
    private void loadLevel()
    {   
        // Carga un nuevo Level.
        int res = fileChooser.showOpenDialog((JFrame)window);

        if(res == JFileChooser.APPROVE_OPTION)
        {
            // Si hay una partida activa la termina.
            finishGame();
        
            File file = fileChooser.getSelectedFile();
            
            try
            {
                window.setLevel(GameController.loadLevel(file));
            }
            catch(Exception e)
            {
                window.showErrorMessage("Error al cargar el archivo: " + e.getMessage());
                return;
            }
        }
        else
            return;

        // Inicializa una nueva partida.
        initGame();
    }
    
    private void loadExampleLevel()
    {
        // Si hay una partida activa la termina.
        finishGame();
        
        // Carga un nuevo Level.
        window.setLevel(GameController.loadTestLevel());
        
        // Inicializa una nueva partida.
        initGame();
    }
    
    
    private void initGame()
    {
        // Level no puede ser null.
        if(window.getLevel() == null)
            throw new RuntimeException("No hay nivel cargado.");
        
        // Se crea un GameController nuevo para cada partida.
        controller = new GameController(window.getLevel());
        // Se registra a la vista en el controlador.
        controller.registerView(window);
        
        // Se registra al controladror en la vista.
        window.registerController(controller);
        
        // Inicializa la pantalla.
        window.initScreen();
        menuItemPause.setSelected(false);
        
        // Inicia el juego.
        controller.startGame();
    }
    
    private void finishGame()
    {
        if(controller != null)
            controller.stopGame();
        
        window.resetScreen();
    }
    
    
    /**
     * @param owner Vista contenedora de los menus.
     */
    public GameMenus(View owner)
    {
        controller = null;
        window = owner;
        
        menus.add(createGameMenu());
        menus.add(createLevelMenu());
    }
    
    /**
     * @return Barra de menu armada.
     */
    public JMenuBar getMenuBar()
    {
        return menus;
    }
    
    
    
    private JMenu createGameMenu()
    {
        /* Menu Juego */
        JMenu menuGame = new JMenu("Juego");
        
        /* MenuItem pausa */
        menuItemPause = new JCheckBoxMenuItem("Pausa");
        menuItemPause.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                pauseGame();
            }
        });
        menuGame.add(menuItemPause);
        
        /* MenuItem salir */
        JMenuItem exit = new JMenuItem("Salir");
        exit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                exitGame();
            }
        });
        menuGame.add(exit);
        
        return menuGame;
    }
    
    private JMenu createLevelMenu()
    {
        /* Menu Partida */
        JMenu menuLevel = new JMenu("Partida");
        
        /* MenuItem guardar */
        JMenuItem save = new JMenuItem("Guardar");
        save.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                saveLevel();
            }
        });
        menuLevel.add(save);
        
        /* MenuItem cargar */
        JMenuItem load = new JMenuItem("Cargar");
        load.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                loadLevel();
            }
        });
        menuLevel.add(load);
        
        /* MenuItem cargar */
        JMenuItem loadex = new JMenuItem("Cargar ejemplo");
        loadex.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                loadExampleLevel();
            }
        });
        menuLevel.add(loadex);
        
        return menuLevel;
    }
}
